<?php

namespace addons\shopro\library\commission;

use addons\shopro\library\Oper;
use addons\shopro\model\commission\Level as LevelModel;
use addons\shopro\model\commission\Order as OrderModel;
use addons\shopro\model\commission\Reward as RewardModel;
use addons\shopro\model\User as UserModel;
use addons\shopro\model\commission\Agent as AgentModel;

/**
 * 结算奖金
 */
class Reward
{
    // 分销订单业绩状态 table: commission_order, field: commission_order_status
    const COMMISSION_ORDER_STATUS_NO = 0;  // 不计入
    const COMMISSION_ORDER_STATUS_YES = 1;  // 已计入
    const COMMISSION_ORDER_STATUS_BACK = -1;  // 已退回
    const COMMISSION_ORDER_STATUS_CANCEL = -2;  // 已取消
    // 分销订单佣金处理状态 table: commission_order, field: commission_reward_status
    // 分销佣金状态  table: commission_reward, field: status
    const COMMISSION_REWARD_STATUS_WAITING = 0;  // 未结算、待入账
    const COMMISSION_REWARD_STATUS_ACCOUNTED = 1;  // 已结算、已入账
    const COMMISSION_REWARD_STATUS_BACK = -1;  // 已退回
    const COMMISSION_REWARD_STATUS_CANCEL = -2;  // 已取消
    const COMMISSION_REWARD_STATUS_FROZEN = 2;   // 已冻结
    protected $oper = null;
    
    /**
     * 执行奖金计划,直接派发佣金
     * 
     * @param string    $event                     分佣的事件
     * @param mixed     $commissionOrder|$commissionOrderId           分销订单 
     * @param array     $oper                      操作人
     */
    public function __construct($oper = null)
    {
        if ($oper) {
            $this->oper = $oper;
        } else {
            $this->oper = Oper::set();
        }
    }
    
    /**
     * 执行奖金计划, 派发整单佣金
     * 
     * @param string     $event                      事件
     * @param mixed     $commissionOrder|$commissionOrderId           分销订单 
     */
    public function runCommissionRewardByOrder($event, $commissionOrder)
    {
        if (is_numeric($commissionOrder)) {
            $commissionOrder = OrderModel::get($commissionOrder);
        }

        // 未找到分销订单
        if (!$commissionOrder) {
            return false;
        }

        // 已经操作过了
        if ($commissionOrder['commission_reward_status'] !== self::COMMISSION_REWARD_STATUS_WAITING) {
            return false;
        }

        $commissionEvent = $commissionOrder['commission_event'];

        // 不满足分佣事件
        if ($commissionEvent !== $event && $event !== 'admin') {
            return false;
        }

        // 获取分销商信息
        $agent = AgentModel::get($commissionOrder['agent_id']);
        if (!$agent) {
            return false;
        }

        // 更新分销订单结算状态
        $commissionOrder->commission_reward_status = self::COMMISSION_REWARD_STATUS_ACCOUNTED;
        $commissionOrder->commission_time = time();
        $commissionOrder->save();

        // 直接派发当前订单的佣金
        $commissionRewards = RewardModel::where([
            'commission_order_id' => $commissionOrder['id'],
            'status' => self::COMMISSION_REWARD_STATUS_WAITING,
        ])->group('agent_id')->select();

        if ($commissionRewards) {
            foreach ($commissionRewards as $commissionReward) {
                //直推数量
                $level1 = RewardModel::where([
                    'agent_id' => $commissionReward['agent_id'],
                    'status' => self::COMMISSION_REWARD_STATUS_WAITING,
                    'commission_level' => 1,
                ])->select();
                if(count($level1) > 0 && count($level1) % 3 == 0){
                    foreach ($level1 as $levelval){
                        $this->runCommissionReward($event, $levelval);
                    }
                }
                //间推数量
                $level2 = RewardModel::where([
                    'agent_id' => $commissionReward['agent_id'],
                    'status' => self::COMMISSION_REWARD_STATUS_WAITING,
                    'commission_level' => 2,
                ])->select();
                if(count($level2) > 0 && count($level2) % 3 == 0){
                    foreach ($level2 as $level2val){
                        $this->runCommissionReward($event, $level2val);
                    }
                }

            }
            return true;
        }else {
            return true;
        }

        // 检查是否满足释放条件（3单或3的倍数）
        // 注意：计数已经在Commission.php的addCommissionOrder方法中增加过了
//        if ($this->canReleaseCommission($agent->commission_order_count)) {
//            // 满足条件，更新分销订单结算状态为已入账
//            $commissionOrder->commission_reward_status = self::COMMISSION_REWARD_STATUS_ACCOUNTED;
//            $commissionOrder->commission_time = time();
//            $commissionOrder->save();
//
//            // 释放之前冻结的佣金（包括当前订单）
//            $this->releaseFrozenCommission($commissionOrder->agent_id);
//
//            // 直接派发当前订单的佣金
//            $commissionRewards = RewardModel::all([
//                'commission_order_id' => $commissionOrder['id'],
//                'status' => self::COMMISSION_REWARD_STATUS_WAITING,
//            ]);
//
//            if ($commissionRewards) {
//                foreach ($commissionRewards as $commissionReward) {
//                    $this->runCommissionReward($event, $commissionReward);
//                }
//                return true;
//            }
//        } else {
//            // 不满足条件，保持订单状态为未结算，佣金状态为待入账
//            // 注意：这里不再更新订单状态为冻结，也不冻结佣金，而是保持原状态
//            // 佣金默认就是待入账状态（status=0），不需要额外操作
//            // 但为了确保状态正确，我们显式地设置佣金状态为待入账
//            $commissionRewards = RewardModel::all([
//                'commission_order_id' => $commissionOrder['id'],
//                'status' => self::COMMISSION_REWARD_STATUS_WAITING,
//            ]);
//
//            // 如果没有找到待入账的佣金记录，检查是否需要创建或更新状态
//            if (empty($commissionRewards)) {
//                // 查找所有该订单的佣金记录，确保它们的状态是待入账
//                $allRewards = RewardModel::all([
//                    'commission_order_id' => $commissionOrder['id'],
//                ]);
//
//                foreach ($allRewards as $reward) {
//                    // 确保佣金状态为待入账
//                    if ($reward->status !== self::COMMISSION_REWARD_STATUS_WAITING) {
//                        $reward->status = self::COMMISSION_REWARD_STATUS_WAITING;
//                        $reward->save();
//                    }
//                }
//            }
//
//            return true;
//        }

        return false;
    }

    /**
     * 冻结佣金
     * 
     * @param string     $event                      事件
     * @param mixed     $commissionReward|$commissionRewardId           奖金记录 
     */
    public function freezeCommissionReward($event, $commissionReward)
    {
        if (is_numeric($commissionReward)) {
            $commissionReward = RewardModel::get($commissionReward);
        }

        // 未找到奖金记录
        if (!$commissionReward) {
            return false;
        }

        if ($commissionReward->status == self::COMMISSION_REWARD_STATUS_WAITING) {
            // 更新佣金状态为冻结
            $commissionReward->status = self::COMMISSION_REWARD_STATUS_FROZEN;
            $commissionReward->save();
            
            // 记录日志
            $rewardAgent = new Agent($commissionReward->agent_id);
            Log::write($rewardAgent->user->id, 'reward', [
                'action' => $event . '_frozen',
                'reward' => $commissionReward
            ], $this->oper);
            return true;
        }
        return false;
    }

    /**
     * 检查是否满足释放佣金的条件（3单或3的倍数）
     * 
     * @param int $orderCount 分销商订单计数
     * @return bool
     */
    private function canReleaseCommission($orderCount)
    {
        // 满足3单或3的倍数
        return ($orderCount > 0 && $orderCount % 3 == 0);
    }

    /**
     * 释放冻结的佣金
     * 
     * @param int $agentId 分销商ID
     */
    private function releaseFrozenCommission($agentId)
    {
        // 获取该分销商所有冻结的佣金记录（包括当前订单）
        $frozenRewards = RewardModel::all([
            'agent_id' => $agentId,
            'status' => self::COMMISSION_REWARD_STATUS_FROZEN,
        ]);

        // 释放所有冻结的佣金
        foreach ($frozenRewards as $reward) {
            $this->releaseCommissionReward('release', $reward);
        }
        
        // 同时也要处理当前订单的待入账佣金
        // 获取当前分销商所有待入账的佣金记录
        $waitingRewards = RewardModel::all([
            'agent_id' => $agentId,
            'status' => self::COMMISSION_REWARD_STATUS_WAITING,
        ]);
        
        // 释放所有待入账的佣金
        foreach ($waitingRewards as $reward) {
            $this->runCommissionReward('release', $reward);
        }
        
        // 同步更新所有相关订单的状态为已结算
        $this->updateRelatedOrderStatus($agentId);
    }
    
    /**
     * 更新相关订单状态为已结算
     * 
     * @param int $agentId 分销商ID
     */
    private function updateRelatedOrderStatus($agentId)
    {
        // 获取该分销商所有未结算的订单（包括等待入账和已冻结的订单）
        // 修正SQL语法错误，使用正确的数组查询方式
        $unprocessedOrders = OrderModel::where('agent_id', $agentId)
            ->whereIn('commission_reward_status', [
                self::COMMISSION_REWARD_STATUS_WAITING, 
                self::COMMISSION_REWARD_STATUS_FROZEN
            ])
            ->select();
        
        // 更新这些订单的状态为已结算
        foreach ($unprocessedOrders as $order) {
            $order->commission_reward_status = self::COMMISSION_REWARD_STATUS_ACCOUNTED;
            $order->commission_time = time();
            $order->save();
        }
    }

    /**
     * 释放佣金
     * 
     * @param string     $event                      事件
     * @param mixed     $commissionReward|$commissionRewardId           奖金记录 
     */
    public function releaseCommissionReward($event, $commissionReward)
    {
        if (is_numeric($commissionReward)) {
            $commissionReward = RewardModel::get($commissionReward);
        }

        // 未找到奖金记录
        if (!$commissionReward) {
            return false;
        }

        if ($commissionReward->status == self::COMMISSION_REWARD_STATUS_FROZEN) {
            $rewardAgent = new Agent($commissionReward->agent_id);
            if ($rewardAgent && $rewardAgent->isAgentAvaliable()) {
                $rewardAgent->agent->setInc('total_income', $commissionReward->commission);
                UserModel::money($commissionReward->commission, $commissionReward->agent_id,  'commission_income', $commissionReward->id, '', $commissionReward);
                $commissionReward->status = self::COMMISSION_REWARD_STATUS_ACCOUNTED;
                $commissionReward->save();
                Log::write($rewardAgent->user->id, 'reward', [
                    'action' => $event,
                    'reward' => $commissionReward
                ], $this->oper);
                return true;
            }
        }
        return false;
    }

    /**
     * 执行奖金计划,直接派发佣金
     * 
     * @param string     $event                      事件
     * @param mixed     $commissionReward|$commissionRewardId           奖金记录 
     */
    public function runCommissionReward($event, $commissionReward)
    {
        if (is_numeric($commissionReward)) {
            $commissionReward = RewardModel::get($commissionReward);
        }

        // 未找到奖金记录
        if (!$commissionReward) {
            return false;
        }

        if ($commissionReward->status == self::COMMISSION_REWARD_STATUS_WAITING) {
            $rewardAgent = new Agent($commissionReward->agent_id);
            if ($rewardAgent && $rewardAgent->isAgentAvaliable()) {
                $rewardAgent->agent->setInc('total_income', $commissionReward->commission);
                UserModel::money($commissionReward->commission, $commissionReward->agent_id,  'commission_income', $commissionReward->id, '', $commissionReward);
                $commissionReward->status = self::COMMISSION_REWARD_STATUS_ACCOUNTED;
                $commissionReward->save();
                Log::write($rewardAgent->user->id, 'reward', [
                    'action' => $event,
                    'reward' => $commissionReward
                ], $this->oper);
                return true;
            }
        }
        return false;
    }


    /**
     * 扣除/取消 分销订单
     * 
     * @param string   $event                     事件
     * @param mixed    $commissionOrder|$commissionOrderId           分销订单 
     * @param array     $deleteOrder               扣除分销商的订单业绩  默认扣除
     * @param array     $deleteReward              扣除分销订单奖金     默认扣除
     */
    public function backCommissionRewardByOrder($event, $commissionOrder, $deleteOrder = true, $deleteReward = true)
    {
        if ($event == 'refund') {
            $config = new Config();
            $deleteOrder = $config->getRefundCommissionOrder();
            $deleteReward = $config->getRefundCommissionReward();
        }

        if (!$deleteOrder && !$deleteReward) {
            return false;
        }

        if (is_numeric($commissionOrder)) {
            $commissionOrder = OrderModel::get($commissionOrder);
        }

        // 未找到分销订单
        if (!$commissionOrder) {
            return false;
        }

        // 扣除分销商的订单业绩
        if ($deleteOrder) {
            // 变更分销订单状态
            if ($commissionOrder->commission_order_status == self::COMMISSION_ORDER_STATUS_YES) {    // 扣除
                $commissionOrder->commission_order_status = self::COMMISSION_ORDER_STATUS_BACK;
                $commissionOrder->save();
            }
            if ($commissionOrder->commission_order_status == self::COMMISSION_ORDER_STATUS_NO) {    // 取消
                $commissionOrder->commission_order_status = self::COMMISSION_ORDER_STATUS_CANCEL;
                $commissionOrder->save();
            }
            $orderAgent = new Agent($commissionOrder->agent_id);
            // 扣除分销订单业绩
            if ($commissionOrder->commission_order_status == self::COMMISSION_ORDER_STATUS_BACK) {
                if ($orderAgent->agent->order_money < $commissionOrder->amount) {
                    $orderAgent->agent->order_money = 0;
                    $orderAgent->agent->save();
                } else {
                    $orderAgent->agent->setDec('order_money', $commissionOrder->amount);
                }
                // 减少订单计数
                if ($orderAgent->agent->order_count > 0) {
                    $orderAgent->agent->setDec('order_count', 1);
                }
                $orderAgent->agent->save();
                
                // 业绩变更，重新统计团队业绩
                $orderAgent->asyncAgentUpgrade($orderAgent->agent->user_id);
                Log::write($commissionOrder['agent_id'], 'order', [
                    'action' => $event,
                    'order' => $commissionOrder,
                    'buyer' => \addons\shopro\model\User::get($commissionOrder->buyer_id)
                ], $this->oper);
            }
        }

        // 变更分销订单佣金执行状态
        if ($deleteReward) {
            if ($commissionOrder->commission_reward_status == self::COMMISSION_REWARD_STATUS_ACCOUNTED) { // 扣除
                $commissionOrder->commission_reward_status = self::COMMISSION_REWARD_STATUS_BACK;
                $commissionOrder->save();
                // 防止重复扣除佣金
                $commissionRewards = RewardModel::all([
                    'commission_order_id' => $commissionOrder->id,
                    'status' => self::COMMISSION_REWARD_STATUS_ACCOUNTED,
                ]);
                // 扣除分销佣金
                if ($commissionRewards) {
                    foreach ($commissionRewards as $commissionReward) {
                        $this->backCommissionReward($event, $commissionReward);
                    }
                }
                return true;
            }

            if ($commissionOrder->commission_reward_status == self::COMMISSION_REWARD_STATUS_FROZEN) {  // 取消冻结的佣金
                $commissionOrder->commission_reward_status = self::COMMISSION_REWARD_STATUS_CANCEL;
                $commissionOrder->save();
                $commissionRewards = RewardModel::all([
                    'commission_order_id' => $commissionOrder->id,
                    'status' => self::COMMISSION_REWARD_STATUS_FROZEN
                ]);
                // 取消冻结的佣金
                if ($commissionRewards) {
                    foreach ($commissionRewards as $commissionReward) {
                        $this->cancelFrozenCommissionReward($event, $commissionReward);
                    }
                }
                return true;
            }

            if ($commissionOrder->commission_reward_status == self::COMMISSION_REWARD_STATUS_WAITING) {  // 取消
                $commissionOrder->commission_reward_status = self::COMMISSION_REWARD_STATUS_CANCEL;
                $commissionOrder->save();
                $commissionRewards = RewardModel::all([
                    'commission_order_id' => $commissionOrder->id,
                    'status' => self::COMMISSION_REWARD_STATUS_WAITING
                ]);
                // 扣除分销佣金
                if ($commissionRewards) {
                    foreach ($commissionRewards as $commissionReward) {
                        $this->cancelCommissionReward($event, $commissionReward);
                    }
                }
                return true;
            }
        }
        return false;
    }

    /**
     * 取消冻结的佣金
     * 
     * @param string     $event                      事件
     * @param mixed     $commissionReward|$commissionRewardId           奖金记录 
     */
    public function cancelFrozenCommissionReward($event, $commissionReward)
    {
        if (is_numeric($commissionReward)) {
            $commissionReward = RewardModel::get($commissionReward);
        }

        // 未找到奖金记录
        if (!$commissionReward) {
            return false;
        }

        if ($commissionReward->status == self::COMMISSION_REWARD_STATUS_FROZEN) {
            $commissionReward->status = self::COMMISSION_REWARD_STATUS_CANCEL;
            $commissionReward->save();

            $rewardAgent = new Agent($commissionReward->agent_id);
            Log::write($rewardAgent->user->id, 'reward', [
                'action' => $event,
                'reward' => $commissionReward,
            ], $this->oper);
            return true;
        }
        return false;
    }

    /**
     * 扣除 分销佣金
     * 
     * @param string     $event                      事件
     * @param mixed     $commissionReward|$commissionRewardId           奖金记录 
     */
    public function backCommissionReward($event, $commissionReward)
    {
        if (is_numeric($commissionReward)) {
            $commissionReward = RewardModel::get($commissionReward);
        }

        // 未找到奖金记录
        if (!$commissionReward) {
            return false;
        }

        if ($commissionReward->status == self::COMMISSION_REWARD_STATUS_ACCOUNTED) {
            $rewardAgent = new Agent($commissionReward->agent_id);
            if ($rewardAgent->agent->total_income < $commissionReward->commission) {
                $rewardAgent->agent->total_income = 0;
                $rewardAgent->agent->save();
            } else {
                $rewardAgent->agent->setDec('total_income', $commissionReward->commission);
            }
            UserModel::money(-$commissionReward->commission, $commissionReward->agent_id, 'commission_back', $commissionReward->id, '', $commissionReward);
            $commissionReward->status = self::COMMISSION_REWARD_STATUS_BACK;
            $commissionReward->save();
            Log::write($rewardAgent->user->id, 'reward', [
                'action' => $event,
                'reward' => $commissionReward,
            ], $this->oper);
            return true;
        }
        return false;
    }

    /**
     * 取消 分销佣金
     * 
     * @param string     $event                      事件
     * @param mixed     $commissionReward|$commissionRewardId           奖金记录 
     */
    public function cancelCommissionReward($event, $commissionReward)
    {
        if (is_numeric($commissionReward)) {
            $commissionReward = RewardModel::get($commissionReward);
        }

        // 未找到奖金记录
        if (!$commissionReward) {
            return false;
        }

        if ($commissionReward->status == self::COMMISSION_REWARD_STATUS_WAITING) {
            $commissionReward->status = self::COMMISSION_REWARD_STATUS_CANCEL;
            $commissionReward->save();

            $rewardAgent = new Agent($commissionReward->agent_id);
            Log::write($rewardAgent->user->id, 'reward', [
                'action' => $event,
                'reward' => $commissionReward,
            ], $this->oper);
            return true;
        }
        return false;
    }
}